#ifndef H_OPTIMIZE
#define H_OPTIMIZE
#include "precompiled.h"
#include "item.h"
#include "character.h"
#include "enchant.h"
#include "optimizationfactory.h"
namespace weo
{
    namespace engine
    {
        namespace optimization
        {
            class Optimization : public virtual gc_cleanup
            {				
            private:			
            protected:
                std::vector<std::vector<const weo::engine::item::Item*>> m_Items;
                unsigned int m_Gemindex;
                weo::engine::character::Character* m_Character;
                boost::signal<void ()> m_EndSignal;		
                boost::signal<void (float)> m_UpdateSignal;
                float m_MaxTV;
                bool m_Abort;
                bool m_Locked[weo::engine::Slotcount];
                weo::engine::character::Equipment m_Equip;
                boost::timer m_StartLoop;
                boost::timer m_Runtime;
                virtual void OptimizeThreadRunner() = 0;
            public:
                weo::engine::character::Character* Character() const {return m_Character;};
                void Character(weo::engine::character::Character* character) {m_Character = character; m_Character->evaluateBuffs();};
                const std::vector<std::vector<const weo::engine::item::Item*>>* Items() const {return &m_Items;};
                void EndSignal(boost::signal<void ()>::slot_function_type slot) {m_EndSignal.connect(slot);};
                void UpdateSignal(boost::signal<void (float)>::slot_function_type slot) {m_UpdateSignal.connect(slot);};
                virtual void Optimize() = 0;
                void setLocked(bool* locked)
                {
                    for(int i = 0;i<weo::engine::Slotcount;i++)
                    {
                        m_Locked[i] = locked[i];
                    }
                }
                Optimization();
                virtual ~Optimization();
                void Abort(bool abort) {m_Abort = abort;};
                const weo::engine::character::Equipment*  getEquip() const {return &m_Equip;};
                void setEquip(const weo::engine::character::Equipment& equip) {m_Equip = equip;};
                virtual std::vector<std::vector<const weo::engine::item::Item*>> filterOptimizeItems(const std::vector<std::vector<const weo::engine::item::Item*>>& value);
                void setItems(const std::vector<std::vector<const weo::engine::item::Item*>>& items);
                virtual inline bool Valid(weo::engine::item::ItemPtr items[weo::engine::Slotcount],weo::engine::item::GemPtr gems[weo::engine::Slotcount],weo::engine::item::EnchantPtr enchants[weo::engine::Slotcount]);
                const weo::engine::item::Enchant* getEnchant(const weo::engine::item::Item& item, unsigned int slot, int nr = -1);
                virtual inline void populateSlot(weo::engine::item::ItemPtr& item, weo::engine::item::GemPtr& gem1, weo::engine::item::GemPtr& gem2, weo::engine::item::GemPtr& gem3, weo::engine::item::EnchantPtr& enchant, int slot, int itemnumber = -1, int gemnumber = -1, int enchantnumber = -1);
            };
        };
    };
};
#endif